package com.dding.cms.base.web.widget.handler;

import static com.dding.cms.base.web.ActionConstants.DEFAULT_CHANGE_FIELDS;
import static com.dding.cms.base.web.ActionConstants.TAG_NAME;
import static com.dding.cms.base.web.ActionConstants.TAG_TABLE_NAME;
import static com.dding.cms.base.web.ActionConstants.UPDATE_DATA_MAP;
import static com.dding.cms.base.web.ActionConstants.WIDGET_REMOVE_ID_KEY;
import static com.dding.cms.base.web.ActionConstants.WIDGET_RESULT_KEY;
import static com.dding.cms.base.web.ActionConstants.WIDGET_TYPE_TEXT;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.dding.core.util.ArrayUtils;
import org.dding.core.util.StringUtils;
import org.javalite.activejdbc.LazyList;
import org.javalite.activejdbc.Model;

import com.dding.cms.base.entity.Content;
import com.dding.cms.base.entity.Tag;
import com.dding.cms.base.web.widget.IWidgetContext;
import com.dding.cms.base.web.widget.WidgetTable;

@WidgetTable(TAG_TABLE_NAME)
public class TagHandler extends DefaultTextHandler {

	@Override
	public Object handleSet(IWidgetContext widgetContext) {

		List<Model> list = new ArrayList<Model>();
		List<String> ids = new ArrayList<String>();

		Map<String, Object> result = new HashMap<String, Object>();
		result.put(WIDGET_RESULT_KEY, list);
		result.put(WIDGET_REMOVE_ID_KEY, ids);

		Map<String, Object> parameter = widgetContext.getParameters();

		String[] value = getParameterSetValue(TAG_NAME, WIDGET_TYPE_TEXT,
				parameter, ids);
		if (value == null || value.length == 0 || StringUtils.isEmpty(value[0])) {
			return result;
		}
		String[] tagValue = value[0].split(",");
		for (String temp : tagValue) {
			Model model = Tag.findFirst(TAG_NAME + "=?", temp);
			if (model != null) {
				Integer counter = model.getInteger("ref_counter");
				model.set("ref_counter", ++counter);
			} else {
				model = new Tag();
				model.set(TAG_NAME, temp);
				model.set("ref_counter", 1);
			}
			model.save();
			list.add(model);
		}
		return result;
	}

	@Override
	public Object handleGet(IWidgetContext widgetContext) {
		String[] result = new String[2];
		result[0] = TAG_NAME;
		StringBuilder builder = new StringBuilder();
		Map<String, Object> map = widgetContext.getParameters();
		for (Object object : map.values()) {
			if (object instanceof LazyList) {
				@SuppressWarnings("unchecked")
				LazyList<? extends Model> list = (LazyList<? extends Model>) object;
				for (Iterator<? extends Model> iterator = list.iterator(); iterator
						.hasNext();) {
					Model model = iterator.next();
					builder.append(model.getString(TAG_NAME));
					builder.append(",");
				}
			}
		}
		String tags = builder.toString();
		if (StringUtils.isNotEmpty(tags)) {
			result[1] = tags.substring(0, tags.length() - 1);
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Object handleUpdateAssociation(IWidgetContext widgetContext) {

		Map<String, Object> data = widgetContext.getParameters();

		Set<String> fields = (Set<String>) data.get(DEFAULT_CHANGE_FIELDS);

		if (fields == null || fields.size() == 0)
			return null;

		Map<String, Object> dataMap = (Map<String, Object>) data
				.get(UPDATE_DATA_MAP);

		String[] value = getParameterSetValue(TAG_NAME, WIDGET_TYPE_TEXT,
				dataMap, null);

		String content_id = ((String[]) dataMap.get("content_id"))[0];

		Model model = Content.findById(content_id);
		LazyList<Tag> tags = model.getAll(Tag.class);

		if (value == null || value.length == 0 || StringUtils.isEmpty(value[0])) {
			if (tags.size() != 0) {
				for (Iterator<Tag> it = tags.iterator(); it.hasNext();) {
					Tag tag = it.next();
					Integer counter = tag.getInteger("ref_counter");
					tag.set("ref_counter", --counter);
					tag.save();
					model.remove(tag);
				}
			}
			return null;
		}

		String[] tagValue = value[0].split(",");
		Iterator<String> itf = fields.iterator();
		while (itf.hasNext()) {
			String field = itf.next();
			if (field.startsWith(TAG_NAME)) {
				for (Iterator<Tag> it = tags.iterator(); it.hasNext();) {
					Tag tag = it.next();
					String tag_name = tag.getString(TAG_NAME);
					if (!ArrayUtils.contains(tagValue, tag_name)) {
						Integer counter = tag.getInteger("ref_counter");
						tag.set("ref_counter", --counter);
						tag.save();
						model.remove(tag);
					}
					tagValue = (String[]) ArrayUtils.removeElement(tagValue,
							tag_name);
				}

				for (String newTag : tagValue) {

					Model tag = Tag.findFirst(TAG_NAME + " = ?", newTag);
					if (tag != null) {
						Integer counter = tag.getInteger("ref_counter");
						tag.set("ref_counter", ++counter);
					} else {
						tag = new Tag();
						tag.set(TAG_NAME, newTag);
						tag.set("ref_counter", 1);
					}
					tag.save();
					model.add(tag);
				}
				itf.remove();
				break;
			}
		}
		return null;
	}
}
